package com.dawn.module.hospital.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dawn.framework.common.pojo.CommonResult;
import com.dawn.framework.common.util.http.HttpUtils;
import com.dawn.module.hospital.controller.app.chs.vo.ChsOauthUserReqVO;
import com.dawn.module.hospital.controller.app.chs.vo.ChsOauthUserRespVO;
import com.dawn.module.hospital.dal.dataobject.chs.config.ChsConfigDO;
import com.dawn.module.hospital.service.chs.config.ChsConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.dawn.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.dawn.module.hospital.enums.ErrorCodeConstants.CHS_CONFIG_NOT_EXISTS;
import static com.dawn.module.hospital.enums.ErrorCodeConstants.CHS_USER_QUERY_OUT;

/**
 * @description: 医保移动支付授权
 * @author: cnsu-cmh
 * @time: 2024/8/8 18:06
 */
@Slf4j
@Service
public class ChsChannelOauthService extends BHService {

    private final static char[] hexArray = "0123456789abcdef".toCharArray();

    @Resource
    private ChsConfigService chsConfigService;

    public CommonResult userQuery(ChsOauthUserReqVO reqVO) {
        ChsOauthUserRespVO respVO = new ChsOauthUserRespVO();
        ChsConfigDO chsConfigDO = chsConfigService.getChsConfig();
        if (chsConfigDO.getId() == null) {
            throw exception(CHS_CONFIG_NOT_EXISTS);
        }
        String userQueryUrl = formatUserQueryUrl(chsConfigDO);
        JSONObject requestBody = new JSONObject();
        requestBody.put("qrcode",reqVO.getAuthCode());
        requestBody.put("openid",reqVO.getOpenid());
        try {
            String userQueryRsp = postData(userQueryUrl, chsConfigDO.getPartnerSecret(), chsConfigDO.getPartnerId(), requestBody);
            if(StringUtils.isBlank(userQueryRsp)) {
                throw exception(CHS_USER_QUERY_OUT);
            }
            JSONObject rspJson = JSON.parseObject(userQueryRsp);
            int code = rspJson.getIntValue("code");
            if(code == 0) {
                String pay_auth_no = rspJson.getString("pay_auth_no");
                JSONObject user_longitude_latitude = rspJson.getJSONObject("user_longitude_latitude");
                String longitude = user_longitude_latitude.getString("longitude");
                String latitude = user_longitude_latitude.getString("latitude");
                String uldLatlnt = longitude+","+latitude;
                respVO.setPayAuthNo(pay_auth_no);
                respVO.setUldLatlnt(uldLatlnt);
                respVO.setLongitude(longitude);
                respVO.setLatitude(latitude);
            } else {
                String message = rspJson.getString("message");
                return CommonResult.error(-1,message);
            }
        }catch (Exception e){
            e.printStackTrace();
            return CommonResult.error(-1,e.getMessage());
        }
        return CommonResult.success(respVO);
    }

    private String createSignature(String partnerSecret, String partnerId, String timestamp)
            throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(partnerSecret.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        return bytesToHex(sha256_HMAC.doFinal((partnerId + timestamp).getBytes("UTF-8")));
    }

    private String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0Xff;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    private String postData(String userQueryUrl,String partnerSecret,String partnerId,JSONObject data) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        String timestamp = Long.toString(System.currentTimeMillis());
        String signature = createSignature(partnerSecret, partnerId, timestamp);
        String requestId = UUID.randomUUID().toString().replaceAll("-", "");

        Map headers = new HashMap<String,String>();
        headers.put("god-portal-timestamp",timestamp);
        headers.put("god-portal-signature",signature);
        headers.put("god-portal-request-id", requestId);
        log.info("userQuery postData userQueryUrl = " + userQueryUrl);
        log.info("userQuery postData headers = " + JSON.toJSONString(headers));
        log.info("userQuery postData requestBody = " + JSON.toJSONString(data));
        String json = HttpUtils.postJson(userQueryUrl,data, headers );
        log.info("userQuery postData resp = " + json);
        return json;
    }

    private String formatUserQueryUrl(ChsConfigDO chsConfigDO) {
        String url = chsConfigDO.getChannelUserUrl()+"/"+chsConfigDO.getPartnerId();
        log.info("formatUserQueryUrl =" + url);
        return url;
    }

}
